// ignore: depend_on_referenced_packages
import 'package:dio/dio.dart';
import 'package:freezed_annotation/freezed_annotation.dart';

import '../config/api_constants.dart';
import '../exceptions/api_exceptions.dart';

part 'api_response.g.dart';

@immutable
class ApiResponse<T> {
  final T? data;
  final ApiException? error;
  final Map<String, dynamic> headers;

  const ApiResponse({
    this.data,
    this.error,
    this.headers = const {},
  });

  factory ApiResponse.success({
    required T data,
    Map<String, dynamic> headers = const {},
  }) =>
      ApiResponse<T>(data: data, headers: headers);

  factory ApiResponse.error(ApiException error) => ApiResponse<T>(error: error);

  bool get isSuccess => error == null;

  R when<R>({
    required R Function(T data) success,
    required R Function(ApiException error) error,
  }) {
    if (isSuccess) {
      return success(data as T);
    } else {
      return error(this.error!);
    }
  }
}

// 基础响应模型，代码生成需要freezed_annotation
@JsonSerializable(genericArgumentFactories: true)
class BaseResponse<T> {
  final int code;
  final String message;
  final T? data;

  BaseResponse({
    required this.code,
    required this.message,
    this.data,
  });

  factory BaseResponse.fromJson(
    Map<String, dynamic> json,
    T Function(Object? json) fromJsonT,
  ) =>
      _$BaseResponseFromJson(json, fromJsonT);

  bool get isSuccess => code == ApiConstants.successCode;

  Map<String, dynamic> toJson(Object? Function(T value) toJsonT) =>
      _$BaseResponseToJson(this, toJsonT);
}

// * 缓存响应模型
class CachedResponse<T> extends Response<T> {
  CachedResponse({
    required super.requestOptions,
    super.data,
    super.statusCode,
  }) : setDateTime = DateTime.now();

  factory CachedResponse.fromResponse(Response<T> response) {
    return CachedResponse<T>(
      requestOptions: response.requestOptions,
      data: response.data,
      statusCode: response.statusCode,
    );
  }

  final DateTime setDateTime;
}
